package com.ja.openchat.viewmodels;

import android.app.Application;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableInt;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.ja.openchat.R;
import com.ja.openchat.data.RegisterVue;
import com.ja.openchat.http.HttpVueClient;
import com.ja.openchat.ui.login.PhoneCodeFragment;
import com.ja.openchat.ui.login.SetNickNameFragment;
import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.model.Response;
import com.sahooz.library.Country;
import com.sahooz.library.CountryPickFragment;
import com.xinstall.XInstall;
import com.xinstall.listener.XInstallAdapter;
import com.xinstall.model.XAppData;
import com.zy.openchat.App;
import com.zy.openchat.core.manager.TelegramManager;
import com.zy.openchat.core.manager.TgEvent;
import com.zy.openchat.core.manager.TgResponse;
import com.zy.openchat.core.manager.TgResultBlock;
import com.zy.openchat.core.model.config.AppConfigInfo;
import com.zy.openchat.core.model.user.UserInfo;

import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONObject;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingAction;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.binding.command.BindingConsumer;
import me.goldze.mvvmhabit.bus.Messenger;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.utils.KLog;

import static com.blankj.utilcode.util.StringUtils.getString;


public class RegisterViewModel extends BaseViewModel {

    public String channelStr = "";
    public String inviteStr = "";

    //用户名的绑定
    public ObservableField<String> userName = new ObservableField<>("");
    //密码的绑定
    public ObservableField<String> password = new ObservableField<>("");
    public ObservableField<String> password1 = new ObservableField<>("");
    //手机号的绑定
    public ObservableField<String> userPhone = new ObservableField<>("");
    public ObservableField<String> userCode = new ObservableField<>("");
    //国家和区号的绑定
    public ObservableField<Country> country = new ObservableField<>(new Country(86, App.getInstanse().getString(R.string.china_text), "CN", 0));
    //用户名清除按钮的显示隐藏绑定
    public ObservableInt clearBtnVisibility = new ObservableInt(View.INVISIBLE);
    public ObservableInt pwdBtnVisibility = new ObservableInt(View.INVISIBLE);
    public ObservableInt pwdBtnVisibility1 = new ObservableInt(View.INVISIBLE);
    public ObservableInt phoneViewVisibility = new ObservableInt(View.VISIBLE);
    public ObservableInt inviterViewVisibility = new ObservableInt(View.VISIBLE);
    //封装一个界面发生改变的观察者
    public UIChangeObservable uc = new UIChangeObservable();
    public static final String TOKEN_REGISTERVIEWMODEL_FINISH = "token_registerviewmodel_finish";
    AppConfigInfo appConfigInfo;

    public class UIChangeObservable {
        //密码开关观察者
        public SingleLiveEvent<Boolean> pSwitchEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<Boolean> pSwitchEvent1 = new SingleLiveEvent<>();
        //倒计时观察者
        public SingleLiveEvent<String> timerEvent = new SingleLiveEvent<>();
    }

    public RegisterViewModel(@NonNull Application application) {
        super(application);
        uc.timerEvent.setValue(App.getInstanse().getString(R.string.verify_code));
        appConfigInfo = AppConfigInfo.getAppWithoutLoginConfigInfo();
        initAppConfigInfo();
        Messenger.getDefault().register(this, TOKEN_REGISTERVIEWMODEL_FINISH, () -> finish());
    }

    public void setCountry(String country) {
        this.country.set(Country.fromJson(country));
    }


    //清除用户名的点击事件, 逻辑从View层转换到ViewModel层
    public BindingCommand clearUserNameOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            userPhone.set("");
        }
    });
    //用户名长度改变的回调事件
    public BindingCommand onTextChangeCommand = new BindingCommand<>(new BindingConsumer<String>() {
        @Override
        public void call(String s) {
            KLog.d("onTextChangeCommand==" + s);
            if (TextUtils.isEmpty(s)) {
                clearBtnVisibility.set(View.INVISIBLE);
            } else {
                clearBtnVisibility.set(View.VISIBLE);
            }
        }
    });
    //用户名输入框焦点改变的回调事件
    public BindingCommand<Boolean> onFocusChangeCommand = new BindingCommand<>(new BindingConsumer<Boolean>() {
        @Override
        public void call(Boolean hasFocus) {
            if (hasFocus && !TextUtils.isEmpty(userPhone.get())) {
                clearBtnVisibility.set(View.VISIBLE);
            } else {
                clearBtnVisibility.set(View.INVISIBLE);
            }
        }
    });
    public BindingCommand<Boolean> onPwdFocusChangeCommand = new BindingCommand<>(new BindingConsumer<Boolean>() {
        @Override
        public void call(Boolean hasFocus) {
            if (hasFocus) {
                pwdBtnVisibility.set(View.VISIBLE);
            } else {
                pwdBtnVisibility.set(View.INVISIBLE);
            }
        }
    });
    public BindingCommand<Boolean> onPwdFocusChangeCommand1 = new BindingCommand<>(new BindingConsumer<Boolean>() {
        @Override
        public void call(Boolean hasFocus) {
            if (hasFocus) {
                pwdBtnVisibility1.set(View.VISIBLE);
            } else {
                pwdBtnVisibility1.set(View.INVISIBLE);
            }
        }
    });
    //选择国家按钮的点击事件
    public BindingCommand countryOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            startContainerActivityForResult(CountryPickFragment.class.getCanonicalName(), 1);
        }
    });
    //点击验证码
    public BindingCommand phoneCodeClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            //国家码
            if (StringUtils.isEmpty(country.get().codeStr)) {
                showWarnTip(getString(R.string.country_code_null_hint));
                return;
            }
            //手机号码
            if (StringUtils.isEmpty(userPhone.get())) {
                showWarnTip(getString(R.string.phone_null_hint));
                return;
            }
            addSubscribe(Flowable.intervalRange(0, 60, 0, 1, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnNext(aLong -> {
                        int time = (int) (59 - aLong);
                        KLog.d("aLong==" + time);
                        if (time > 0) {
                            uc.timerEvent.setValue(time + getString(R.string.second_text));
                        } else {
                            uc.timerEvent.setValue(getString(R.string.verify_code));
                        }
                    })
                    .doOnComplete(() -> {
                        //倒计时完毕事件处理
                        KLog.d("doOnComplete==");
                        uc.timerEvent.setValue(getString(R.string.verify_code));
                    })
                    .subscribe());
//            getPhoneCode();
        }
    });
    //注册按钮的点击事件
    public BindingCommand loginOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            login();
        }
    });

    //密码显示开关  (你可以尝试着狂按这个按钮,会发现它有防多次点击的功能)
    public BindingCommand passwordShowSwitchOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            //让观察者的数据改变,逻辑从ViewModel层转到View层，在View层的监听则会被调用
            uc.pSwitchEvent.setValue(uc.pSwitchEvent.getValue() == null || !uc.pSwitchEvent.getValue());
        }
    });

    //密码显示开关 1 (你可以尝试着狂按这个按钮,会发现它有防多次点击的功能)
    public BindingCommand passwordShowSwitchOnClickCommand1 = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            //让观察者的数据改变,逻辑从ViewModel层转到View层，在View层的监听则会被调用
            uc.pSwitchEvent1.setValue(uc.pSwitchEvent1.getValue() == null || !uc.pSwitchEvent1.getValue());
        }
    });

    private void login() {
//        startContainerActivity(PhoneCodeFragment.class.getCanonicalName());
        check();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onTgEvent(final TgEvent tg_event) {
        switch (tg_event.event) {
            case EUser_App_All_Config_Changed:
                appConfigInfo = AppConfigInfo.getAppWithoutLoginConfigInfo();
                initAppConfigInfo();
                break;
            case EUser_Td_Input_Code:
                if (appConfigInfo != null && appConfigInfo.register_need_phone_code) {
                    Bundle bundle = new Bundle();
                    bundle.putString("code", "+" + country.get().code);
                    bundle.putString("phone", userPhone.get());
                    bundle.putString("userName", userName.get());
                    bundle.putString("password", password.get());
                    bundle.putString("channelStr", channelStr);
                    String inviteStrLim = appConfigInfo.register_need_inviter ? userCode.get() : inviteStr;
                    bundle.putString("inviteStr", inviteStrLim);
                    startContainerActivity(PhoneCodeFragment.class.getCanonicalName(), bundle);
                } else {
                    showProgress();
                    TelegramManager.getTelegramManager().checkAuthenticationCode(getApplication(), "88888", new TgResultBlock<TgResponse>() {
                        @Override
                        public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                            hideProgress();
                            if (!obj.ok) {
                                if (obj.errCode == 420) {//验证码错误次数过多，请5分钟后重新登录
                                    showErrorTip(getString(R.string.invalid_sms_code_is_block));
                                    finish();
                                } else {
                                    showErrorTip(getString(R.string.invalid_sms_code));
                                }
                            }
                        }

                        @Override
                        public void onTimeout(Map<String, Object> request) {
                            hideProgress();
                            showErrorTip(getString(R.string.request_error));
                        }
                    });
                }
                break;
            case EUser_Td_Register:
                XInstall.reportRegister();
                Bundle bundle = new Bundle();
                bundle.putString("curUsername", userName.get());
                bundle.putString("userCode", userCode.get());
                startContainerActivity(SetNickNameFragment.class.getCanonicalName(), bundle);
                break;
            default:
                break;
        }
    }


    private void initAppConfigInfo() {
        if (appConfigInfo == null)
            return;
        phoneViewVisibility.set(appConfigInfo.register_need_phone_code ? View.VISIBLE : View.GONE);
        inviterViewVisibility.set(appConfigInfo.register_need_inviter ? View.VISIBLE : View.GONE);


        XInstall.getInstallParam(new XInstallAdapter() {
            @Override
            public void onInstall(XAppData XAppData) {
                //获取渠道数据
                String channelCode = XAppData.getChannelCode();

                //获取数据
                Map<String, String> data = XAppData.getExtraData();
                //通过链接后面携带的参数或者通过WebSdk初始化传入的data值。
                String uo = data.get("uo");
                //WebSdk初始，在buttonId里面定义的按钮点击携带数据
                String co = data.get("co");

                //获取时间戳
                String timeSpan = XAppData.getTimeSpan();
                //是否为第一次获取到安装参数
                boolean firstFetch = XAppData.isFirstFetch();

                if (TextUtils.isEmpty(uo)) {

                } else {
                    try {
                        JSONObject uoJson = new JSONObject(uo);
                        if (uoJson.has("channel")) {
                            channelStr = uoJson.getString("channel");
                        }
                        if (uoJson.has("invite")) {
                            inviteStr = uoJson.getString("invite");
                            userCode.set(inviteStr);
                        }
                    } catch (Exception error) {

                    }
                }
            }
        });

    }

    private void check() {
        if (appConfigInfo != null && appConfigInfo.register_need_phone_code) {
            if (TextUtils.isEmpty(country.get().codeStr)) {
                showWarnTip(getString(R.string.country_code_null_hint));
                return;
            }

            if (TextUtils.isEmpty(userPhone.get())) {
                showWarnTip(getString(R.string.phone_null_hint));
                return;
            }
        }
        if (TextUtils.isEmpty(userName.get())) {
            showWarnTip(getString(R.string.edit_username_hint));
            return;
        }
        if (TextUtils.isEmpty(password.get())) {
            showWarnTip(getString(R.string.password_hint));
            return;
        }
        if (TextUtils.isEmpty(password1.get())) {
            showWarnTip(getString(R.string.edit_repeat_account_password_hint));
            return;
        }
        if (!password.get().equals(password1.get())) {
            showWarnTip(getString(R.string.pwd_not_match));
            return;
        }
//        if (appConfigInfo != null && appConfigInfo.register_need_inviter) {
            if (TextUtils.isEmpty(userCode.get())) {
                showWarnTip(getString(R.string.edit_invite_code_text));
                return;
            }
//        }
        sendCode();
    }

    private void sendCode() {
        UserInfo.getUserInfo().isPasswordLoginType = true;
        UserInfo.getUserInfo().isPasswordRegisterType = true;
        UserInfo.getUserInfo().phone_number = null;
        showProgress();
        String phone = "";
        if (appConfigInfo != null) {
            phone = appConfigInfo.register_need_phone_code ? String.format("%s%s", country.get().code + "", userPhone.get()).replace("+", "") : "";
        }
//        String inviteStrLim = appConfigInfo.register_need_inviter ? userCode.get() : inviteStr;
        String inviteStrLim = appConfigInfo.register_need_inviter ? userCode.get() : "";
        TelegramManager.getTelegramManager().setAuthenticationPhoneNumber(getApplication()
                , true, phone
                , userName.get()
                , password.get()
                , channelStr
                , inviteStrLim, new TgResultBlock<TgResponse>() {
                    @Override
                    public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                        hideProgress();
                        if (!obj.ok) {
//                            Bundle bundle = new Bundle();
//                            bundle.putString("code", "+" + country.get().code);
//                            bundle.putString("phone", userPhone.get());
//                            bundle.putString("userName", userName.get());
//                            bundle.putString("password", password.get());
//                            bundle.putString("channelStr", channelStr);
//                            startContainerActivity(PhoneCodeFragment.class.getCanonicalName(), bundle);
                            if (obj.errCode == 400) {
                                if ("400_USERNAME_NOT_EXIST".equals(obj.errString) || "400_USERNAME_INVALID".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.invalid_username));
                                    return;
                                }
                                if ("400_PASSWORD_VERIFY_INVALID".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.invalid_password));
                                    return;
                                }
                                if ("400_IP_ADDRESS_BANNED".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.login_ip_disabled));
                                    return;
                                }
                                if ("400_USER_BINDED_IP_ADDRESS".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.user_ip_bound));
                                    return;
                                }
                                if ("400_INVITE_CODE_INVALID".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.invitation_code_invalid));
                                    return;
                                }
                                if ("400_PHONE_NUMBER_OCCUPIED".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.mobile_is_registered));
                                    return;
                                }
                                if ("400_PHONE_NUMBER_INVALID".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.invalid_phone_number));
                                    return;
                                }
                                if ("400_USER_PASSWORD_NEEDED".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.pwd_required));
                                    return;
                                }
                                if ("400_INVITE_CODE_INVALID".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.invitation_code_invalid));
                                    return;
                                }
                                if ("400_USER_PASSWORD_NOT_SET".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.pwd_not_set));
                                    return;
                                }
                                if ("400_USERNAME_OCCUPIED".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.username_already_taken));
                                    return;
                                }
                                if ("400_PHONE_NUMBER_APP_SIGNUP_FORBIDDEN".equals(obj.errString)) {
                                    showErrorTip(getApplication().getString(R.string.ip_registration_restrictions));
                                    return;
                                }

                            }
                            showErrorTip(getApplication().getString(R.string.registration_failed));
                        }
                    }

                    @Override
                    public void onTimeout(Map<String, Object> request) {
                        hideProgress();
                        showErrorTip(getString(R.string.request_error));
                    }
                });
    }
}
